/**
    Copyright (c) 2010-2011 yakiimo02
    Distributed under the New BSD License.
    See included license.txt or http://www.yakiimo3d.com/NewBSDLicense.txt
**/

#include "DXUT.h"
#include "CudaMgr.h"
#include "CudaHelper.h"

#pragma warning(push)
#pragma warning(disable:4201 4408)
#include <cuda.h>
#include <builtin_types.h>
#include <cuda_runtime_api.h>
#include <cuda_d3d11_interop.h>
#pragma warning(pop)

CudaMgr g_cudaMgr;

void CudaMgr::Init( ID3D11Device* pd3dDevice )
{
    cudaD3D11SetDirect3DDevice(pd3dDevice);
    CudaCheckForErrors(L"cudaD3D11SetDirect3DDevice failed");
}

void CudaMgr::Destroy()
{
    // Uninitialize CUDA
    cudaThreadExit();
    CudaCheckForErrors(L"cudaThreadExit failed");
}

bool CudaMgr::IsCudaCapableAdapter( const UINT nAdapterOrdinal )
{
    HRESULT hr = S_OK;
    cudaError cuStatus;
    IDXGIAdapter* pAdapter = NULL;

    IDXGIFactory1* pDXGIFactory = DXUTGetDXGIFactory();

    if( pDXGIFactory == NULL ) 
    {
        return false;
    }

    // Get candidate DXGI adapter.
    hr = pDXGIFactory->EnumAdapters( nAdapterOrdinal, &pAdapter );
    if (FAILED(hr))
    {
        return false;
    }

    // Check whether device is cuda capable.
    int cuDevice;
    cuStatus = cudaD3D11GetDevice(&cuDevice, pAdapter);
    if (cudaSuccess == cuStatus)
    {
        pAdapter->Release();
        return true;
    }

    pAdapter->Release();
    return false;
}

